package com.example.hotelsystem.service.impl;

import code.CodeError;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.hotelsystem.config.alipay.AlipayConfig;
import com.example.hotelsystem.delay.DelayQueueManager;
import com.example.hotelsystem.delay.DelayTask;
import com.example.hotelsystem.entity.*;
import com.example.hotelsystem.mapper.HotelorderMapper;
import com.example.hotelsystem.page.Pagesize;
import com.example.hotelsystem.result.Result;
import com.example.hotelsystem.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.hotelsystem.vo.order.OrderDelayVO;
import com.example.hotelsystem.vo.order.OrderSearchVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;


/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Lee
 * @since 2020-10-20
 */
@Service
public class HotelorderServiceImpl extends ServiceImpl<HotelorderMapper, Hotelorder> implements HotelorderService {

    Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    @Autowired
    HotelorderService hotelorderService;

    @Autowired
    UserService userService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RoomService roomService;

    @Autowired
    RoomTypeService RoomTypeService;

    @Autowired
    FloorService floorService;

    @Autowired
    HotelorderMapper hotelorderMapper;

    @Autowired
    RoomTypeService roomTypeService;
    @Autowired
    DelayQueueManager delayQueueManager;
    @Autowired
    TDictService tDictService;
    @Autowired
    HotelNameService hotelNameService;
    @Autowired
    CityService cityService;
    @Autowired
    RoomTypeImageService roomTypeImageService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result createOrder (Long roomId, Long userId, Date checkinTime, Date checkoutTime){
        List<Hotelorder> hotelorders = hotelorderMapper.checkOrder(roomId,checkinTime,checkoutTime);
        logger.info("===================生成订单=======================");
        logger.info(hotelorders);
        if(checkinTime.getTime()==checkoutTime.getTime()){
            return Result.error(CodeError.ORDER_TIME_ERROR,"时间选择有误");
        }
        //List如果存在数据，说明该房间在该时间段已经被人预订
        if(hotelorders.size()!=0){
            return Result.error(CodeError.BOOKING_FAIL,"预定失败，该时间段已有人预定");
        }
        Timestamp t1 = new Timestamp(checkinTime.getTime());
        Timestamp t2 = new Timestamp(checkoutTime.getTime());

        //算出入住天数days
        long day = (t1.getTime()-t2.getTime())/(24*60*60*1000)>0 ? (t1.getTime()-t2.getTime())/(24*60*60*1000):
                (t2.getTime()-t1.getTime())/(24*60*60*1000);
        Room room = roomService.getById(roomId);
        RoomType rt = RoomTypeService.getById(room.getRoomtypeId());

        //生成订单价格
        double price = rt.getPrice() * day;
        Hotelorder order  = new Hotelorder();
        order.setUserId(userId);
        order.setRoomId(roomId);
        order.setCheckoutTime(t2);
        order.setCheckinTime(t1);
        order.setPrice(price);
        order.setStatus(0);
        System.out.println(order);
        boolean isadd = hotelorderService.save(order);
        if (isadd) {
            OrderDelayVO vo = new OrderDelayVO(order.getId());
            DelayTask delayTask = new DelayTask(vo,900000);
            delayQueueManager.put(delayTask);
            HashMap<String, Object> map = new HashMap<>();


            RoomType rtype = roomTypeService.getById(room.getRoomtypeId());
            HotelName hn = hotelNameService.getById(room.getHotelId());


            map.put("id", order.getId());
            map.put("roomNum", room.getNumber());
            map.put("checkin", order.getCheckinTime());
            map.put("checkout", order.getCheckoutTime());
            map.put("price", price);
            map.put("roomTypeName",rtype.getType());
            map.put("HotelName",hn.getHotelName());
            map.put("statusText",tDictService.getDictText(0,"hotelOrderStatus"));
            map.put("createTime", order.getCreateTime());
            logger.info("于"+new Date()+"订单生成成功");
            return Result.success("订单生成成功", map);
        }
        logger.error("订单生成失败");
        return Result.error(CodeError.ORDER_CREATE_FAIL,"订单生成失败");

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String orderPay(HttpServletResponse response, Long id){
        try{
            //获得初始化的AlipayClient
            AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

            //设置请求参数
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            alipayRequest.setReturnUrl(AlipayConfig.return_url);
            alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

            Hotelorder order = hotelorderService.getById(id);
            //商户订单号，商户网站订单系统中唯一订单号，必填
            String out_trade_no = String.valueOf(order.getId());
            //付款金额，必填
            String total_amount =String.valueOf(order.getPrice());

            //订单名称，必填
            String subject = order.getUserId()+ "号用户"+order.getRoomId()+"号房间";

            //商品描述，可空
            String body = String.valueOf(order.getRoomId());
            alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                    + "\"total_amount\":\""+ total_amount +"\","
                    + "\"subject\":\""+ subject +"\","
                    + "\"body\":\""+ body +"\","
                    + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
            //请求
            String form="";
            try {
                form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
            } catch (AlipayApiException e) {
                e.printStackTrace();
            }
            response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
            response.getWriter().write(form);//直接将完整的表单html输出到页面
            response.getWriter().flush();
            response.getWriter().close();
            return form;
        }catch (IOException e){
            e.printStackTrace();
            logger.error(e);
            return e.getMessage();
        }
    }



    @Override
    @Transactional
    public Result searchOrder(OrderSearchVO orderSearchVO){
        try {
            QueryWrapper<Hotelorder> orderQuery = new QueryWrapper<>();


            if(orderSearchVO.getIdcard()!=null){
                QueryWrapper<User> query = new QueryWrapper<>();
                query.eq("is_delete",0);
                query.like("idcard",orderSearchVO.getIdcard());
                List<User> users = userService.list(query);
                List<Long> userids = new ArrayList<>();
                if(users!=null&&users.size()>0){
                    for(User item : users){
                        userids.add(item.getId());
                    }
                }else{
                    userids.add(99999999L);
                }
                orderQuery.in("user_id",userids);
            }

            if(orderSearchVO.getStatus()!=null){
                orderQuery.eq("status",orderSearchVO.getStatus());
            }

            if(orderSearchVO.getCheckinTime()!=null){
                orderQuery.ge("checkin_time",orderSearchVO.getCheckinTime());
            }

            if(orderSearchVO.getCheckoutTime()!=null){
                orderQuery.le("checkout_time",orderSearchVO.getCheckoutTime());
            }

            orderQuery.orderByDesc("pay_time");
            orderQuery.orderByDesc("create_time");
            Page page = new Page(orderSearchVO.getCurrentPage(), Pagesize.pageSize1);
            IPage<Hotelorder> orders=hotelorderService.page(page,orderQuery);
            for(Hotelorder item : orders.getRecords()){
                User u = userService.getById(item.getUserId());
                item.setUserName(u.getUsername());
                item.setIdcard(u.getIdcard());

                Room r = roomService.getById(item.getRoomId());
                RoomType rt = roomTypeService.getById(r.getRoomtypeId());
                HotelName hn = hotelNameService.getById(r.getHotelId());
                City c = cityService.getById(r.getCityId());
                item.setRoomNumber(r.getNumber());
                item.setRoomTypeName(rt.getType());
                item.setHotelName(hn.getHotelName());
                item.setCityName(c.getCityName());
            }

            return Result.success("查询成功",orders);
        }catch (Exception e){
            return Result.error(e.getMessage());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result orderAllList(Integer currentPage){

        HashMap<String,Object> Allmap = new HashMap<>();
        Page page = new Page(currentPage, Pagesize.pageSize1);
        IPage<Hotelorder> orders=hotelorderService.page(page);
        List<Object> newList = new ArrayList<Object>();
//        HashMap<String,Object> pageMap = new HashMap<>();
//        pageMap.put("total",orders.getTotal());
//        pageMap.put("pageSize",orders.getSize());
//        pageMap.put("currentPage",orders.getCurrent());
        if (orders!=null){
            for(Hotelorder order : orders.getRecords()){
//                HashMap<String,Object> map = new HashMap<>();
                Room room = roomService.getById(order.getRoomId());
                User user = userService.getById(order.getUserId());
                Floor floor = floorService.getById(room.getFloorId());
                order.setFloorName(floor.getName());
                RoomType rt = roomTypeService.getById(room.getRoomtypeId());
                order.setRoomTypeName(rt.getType());
                order.setUserName(user.getUsername());
//                map.put("id",order.getId());
//                map.put("roomNum",room.getNumber()!=null?room.getNumber():"房间号丢失");
//                map.put("floorNum",floor.getNumber()!=null?floor.getNumber():"楼层号丢失");
//                map.put("username",user.getUsername()!=null?user.getUsername():"用户名丢失");
//                map.put("userIdCard",user.getIdcard()!=null?user.getIdcard():"身份证号丢失");
//                map.put("checkinTime",order.getCheckinTime());
//                map.put("checkoutTime",order.getCheckoutTime());
//                map.put("price",order.getPrice());
//                map.put("status",order.getStatus());
//                newList.add(map);
            }
//            Allmap.put("page",pageMap);
//            Allmap.put("orderList",newList);
            return Result.success("订单列表获取成功",orders);
        }else {
            return Result.error(CodeError.ORDER_LIST_NULL,"没有找到订单列表");
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result paySuccess(HttpServletRequest request){
        try{
            logger.info("===================订单支付成功=========================");
            String ordCode = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "GBK");
            Long orderId = Long.valueOf(ordCode);
            Hotelorder order = hotelorderService.getById(orderId);

            order.setStatus(1);
            order.setPayTime(new Date());
            hotelorderService.updateById(order);
            delayQueueManager.remove(orderId);
            return Result.success("订单号:"+orderId+"支付成功");
        }catch (Exception e){
            logger.error("捕捉异常:"+e);
            return Result.error(CodeError.INTERNAL_EXCEPTION,"发生异常错误");
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result userOrders(Integer currentPage,Long userId,Long orderStatus){
        QueryWrapper<Hotelorder> query = new QueryWrapper<>();

        if(orderStatus!=null){
            query.eq("status",orderStatus);
        }
        query.orderByDesc("pay_time");
        query.orderByDesc("create_time");

        query.eq("user_id",userId);
        HashMap<String,Object> Allmap = new HashMap<>();
        Page page = new Page(currentPage, Pagesize.pageSize1);
        IPage<Hotelorder> orders=hotelorderService.page(page,query);
//        List<Object> newList = new ArrayList<Object>();
//        HashMap<String,Object> pageMap = new HashMap<>();
//        pageMap.put("total",orders.getTotal());
//        pageMap.put("pageSize",orders.getSize());
//        pageMap.put("currentPage",orders.getCurrent());
        if (orders!=null){
            for(Hotelorder order : orders.getRecords()){
                HashMap<String,Object> map = new HashMap<>();
                Room room = roomService.getById(order.getRoomId());
                User user = userService.getById(order.getUserId());
                Floor floor = floorService.getById(room.getFloorId());
                order.setFloorName(floor.getName());
                RoomType rt = roomTypeService.getById(room.getRoomtypeId());
                order.setRoomTypeName(rt.getType());
                order.setUserName(user.getUsername());
                City city = cityService.getById(room.getCityId());
                order.setCityName(city.getCityName());
                HotelName hotelName = hotelNameService.getById(room.getHotelId());
                order.setHotelName(hotelName.getHotelName());


                QueryWrapper<RoomTypeImage> imageQuery = new QueryWrapper<>();
                imageQuery.eq("room_type_id",rt.getId());
                imageQuery.eq("type",0);
                List<RoomTypeImage> images = roomTypeImageService.list(imageQuery);
                List<String> imageList = new ArrayList<>();
                for(RoomTypeImage item : images){
                    imageList.add(item.getImage());
                }
                order.setImageList(imageList);
            }

            return Result.success("订单列表获取成功",orders);
        }else {
            return Result.error(CodeError.ORDER_LIST_NULL,"没有找到订单列表");
        }
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result ModifyOrder(Hotelorder hotelorder){
        Hotelorder hotelorder1 = hotelorderService.getById(hotelorder.getId());
        BeanUtils.copyProperties(hotelorder, hotelorder1);
        boolean isMod = hotelorderService.updateById(hotelorder1);
        if(isMod){
            return Result.success("修改成功");
        }
        return Result.error(CodeError.ORDER_MOD_FAIL,"修改失败");
    }
}
